package com.ty.springbootshiro.config;


import com.ty.springbootshiro.entity.Right;
import com.ty.springbootshiro.entity.Role;
import com.ty.springbootshiro.entity.User;
import com.ty.springbootshiro.service.RoleService;
import com.ty.springbootshiro.service.UserService;
import jakarta.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.lang.util.ByteSource;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;
import java.util.Set;

/**
 * MyShiroRealm
 *
 * @aurhor Administrator  whs
 * @since 2024/10/8
 */
public class MyShiroRealm extends AuthorizingRealm { // 安全数据源

    @Resource
//    @Lazy
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
//    @Lazy
    private StringRedisTemplate stringRedisTemplate;

    private String SHIRO_LOGIN_COUNT = "shiro_login_count_"; // 登录计数
    private String SHIRO_IS_LOCK = "shiro_is_lock_"; // 锁定用户登录


    // 清空当前认证用户权限缓存
    public void clearMyCachedAuthorizationInfo(PrincipalCollection principals) {
        clearMyCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    // 清空所有用户权限缓存
    public void clearAllCachedAuthorizationInfo(){
        if (this.isAuthorizationCachingEnabled()){  // 权限缓存是否可用
            Cache<Object,AuthorizationInfo> cathe = null;
            CacheManager cacheManager = this.getCacheManager();
            if (cacheManager != null) {
                String cacheName = this.getAuthenticationCacheName(); // 获得缓存名称
                cathe = cacheManager.getCache(cacheName); // 获得权限缓存
            }
            if (cathe != null) {
                cathe.clear(); // 清空
            }
        }
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("调用 MyShiroRealm 的 doGetAuthenticationInfo 获取身份信息");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String usrName = token.getUsername();

        System.out.println("usrName -----------------> " +usrName);

//        // 每次访问，登录次数加1
//        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
//        operations.increment(SHIRO_LOGIN_COUNT + usrName, 1);
//        // 计数大于5时，设置用户锁定一小时，清空登录计数
//        if (Integer.parseInt(operations.get(SHIRO_LOGIN_COUNT + usrName)) > 5 ){
//            operations.set(SHIRO_IS_LOCK + usrName , "LOCK");
//            stringRedisTemplate.expire(SHIRO_LOGIN_COUNT + usrName,1, TimeUnit.HOURS);
//            stringRedisTemplate.delete(SHIRO_LOGIN_COUNT + usrName); // 清空登录计数
//        }
//        if ("LOCK".equals(operations.get(SHIRO_IS_LOCK + usrName))){
//            throw new DisabledAccountException();
//        }


        User user = userService.getUserByName(usrName);

        System.out.println("user ------------------>" +user);

        if (user == null) {
            throw new AuthenticationException();//账号错误
        }
        if (user.getUsrFlag() == null || user.getUsrFlag().intValue() == 0) {
            throw new LockedAccountException();//账号被禁用
        }
        // 修改这里，使用 getName() 方法获取 Realm 的名称，确保与设置 SecurityManager 时一致
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                user,
                user.getUsrPassword(),
                ByteSource.Util.bytes("离别情诗雨"),  // 加密所使用的 salt(盐)
                getName());

        System.out.println("info ---------------->" + info);

        return info;
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("调试myShiroRealm.doGetAuthorizationInfo()获取权限信息");
        User sysUser = (User) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//        info.addRole(sysUser.getRole().getRoleName());
//
//        info.addStringPermission("用户列表"); // 所有用户拥有“用户列表”权限
//        if ("管理员".equals(sysUser.getRole().getRoleName())){  // 管理员有 增删改的权限
//            info.addStringPermission("用户添加");
//            info.addStringPermission("用户编辑");
//            info.addStringPermission("用户删除");
//        }

        // 动态授权
//        Role role = sysUser.getRole();

        Role role = roleService.findRoleByUsers(sysUser);

        System.out.println("role ----------> " + role);
        if (role != null) {
            info.addRole(sysUser.getRole().getRoleName());
//            Set<Right> rights = role.getRights();
            List<Right> rights = roleService.findRightsByRole(role);

            if (rights != null && rights.size() > 0) {
                for (Right right : rights) {
                    info.addStringPermission(right.getRightCode());
                }
            }
        }else {
            System.out.println("没有权限奥~~");
        }

        return info;
    }

}
